#include "Blocks/EggBlock.h"
#include "Blocks/WaterBucketBlock.h"

#include "Utils/Utils.h"
#include "Log.h"
#include "Managers/FurnaceRecipesManager.h"

namespace PocketSurvival
{
    int32_t EggBlock::getIndex()
    {
        return Index();
    }
    const std::string &EggBlock::getBlockName()
    {
        static std::string blockName = "EggBlock";
        return blockName;
    }

    void EggBlock::initialize()
    {
        std::string eggText;
        if (Utils::LoadTextFile("./content/EggData.json", eggText) == true)
        {
            nlohmann::json eggJson = nlohmann::json::parse(eggText);

            for (const auto &eggItemJson : eggJson)
            {
                EggType eggType;
                eggType.eggTypeIndex = eggItemJson["EggTypeIndex"].get<int32_t>();
                eggType.nutritionalValue = eggItemJson["NutritionalValue"].get<float>();
                eggType.showEgg = eggItemJson["ShowEgg"].get<bool>();
                eggType.entityName = eggItemJson["EntityName"].get<std::string>();

                eggTypes.push_back(eggType);

                if (eggType.nutritionalValue > 0.0f)
                {
                    FurnaceRecipe *furnaceRecipe = new FurnaceRecipe;
                    furnaceRecipe->smeltingTimeMultiple = 1;
                    furnaceRecipe->resultCount = 1;
                    furnaceRecipe->resultValue = Terrain::MakeBlockValue(Index(), 0, SetEggType(SetIsCooked(0, true), eggType.eggTypeIndex));
                    furnaceRecipe->remainsCount = 1;
                    furnaceRecipe->remainsValue = Terrain::MakeBlockValue(WaterBucketBlock::Index());
                    furnaceRecipe->requiredHeatLevel = 1;
                    furnaceRecipe->ingredients[0] = Terrain::MakeBlockValue(Index(), 0, SetEggType(SetIsCooked(0, false), eggType.eggTypeIndex));
                    furnaceRecipe->ingredients[1] = WaterBucketBlock::Index();

                    furnaceRecipe->ingredientsDataBit[0] = -244737;
                    furnaceRecipe->ingredientsDataBit[1] = 1023;

                    GameSingleton::furnaceRecipesManager->addFurnaceRecipes(furnaceRecipe);
                }
            }
        }
        else
        {
            Log::Error("加载 ./content/EggData.json 文件数据失败");
        }
    }
    float EggBlock::getNutritionalValue(int32_t value)
    {
        EggType eggType = getEggType(Terrain::ExtractData(value));
        if (GetIsCooked(Terrain::ExtractData(value) == false))
        {
            return eggType.nutritionalValue;
        }
        return 1.5f * eggType.nutritionalValue;
    }

    float EggBlock::getSicknessProbability(int32_t value)
    {
        if (GetIsCooked(Terrain::ExtractData(value)) == false)
        {
            return DefaultSicknessProbability;
        }
        return 0.0f;
    }

    int32_t EggBlock::getRotPeriod(int32_t value)
    {
        if (getNutritionalValue(value) > 0.0f)
        {
            return Block::getRotPeriod(value);
        }
        return 0;
    }

    int32_t EggBlock::getDamage(int32_t value)
    {
        return (Terrain::ExtractData(value) >> 16) & 1;
    }

    int32_t EggBlock::setDamage(int32_t value, int32_t damage)
    {
        int32_t num = Terrain::ExtractData(value);
        num = ((num & -65537) | ((damage & 1) << 16));
        return Terrain::ReplaceData(value, num);
    }

    int32_t EggBlock::getDamageDestructionValue(int32_t value)
    {
        return 246;
    }

    void EggBlock::getCreativeValues(std::vector<int32_t> &blockVec)
    {
        for (const EggType &eggType : eggTypes)
        {
            if (eggType.showEgg == false)
            {
                continue;
            }
            blockVec.push_back(Terrain::MakeBlockValue(Index(), 0, SetEggType(0, eggType.eggTypeIndex)));
            if (eggType.nutritionalValue > 0.0f)
            {
                blockVec.push_back(Terrain::MakeBlockValue(Index(), 0, SetIsCooked(SetEggType(0, eggType.eggTypeIndex), true)));
            }
        }
    }

    const EggType &EggBlock::getEggType(int32_t data)
    {
        int32_t index = (data >> 4) & 0xFFF;
        if (index < eggTypes.size())
        {
            return eggTypes[index];
        }
        static EggType nullEggType{-1, 0.0f};
        return nullEggType;
    }

} // namespace PocketSurvival
